#ifndef POINT_TYPE_H_
#define POINT_TYPE_H_

#include <cstdint>
namespace autodrive {
namespace perception {
/// @brief 2 dim point
/// @tparam T data type
template <typename T>
struct Point2D {
  typedef T type;
  /// @brief x
  T x;
  /// @brief y
  T y;
};

using Point2f = Point2D<float>;
using Point2d = Point2D<double>;
using Point2i = Point2D<std::int32_t>;
using Point2ii = Point2D<std::int64_t>;

/// @brief 3 dim point
/// @tparam T data type
template <typename T>
struct Point3D : Point2D<T> {
  /// @brief z
  T z;
};

using Point3f = Point3D<float>;
using Point3d = Point3D<double>;
using Point3i = Point3D<std::int32_t>;
using Point3ii = Point3D<std::int64_t>;

/// @brief 4 dim point
/// @tparam T data type
template <typename T>
struct Point4D : Point3D<T> {
  /// @brief score
  float score;
};

using Point4f = Point4D<float>;
using Point4d = Point4D<double>;
using Point4i = Point4D<std::int32_t>;
using Point4ii = Point4D<std::int64_t>;

/// @brief multi dim point
/// @tparam T xyz type
/// @tparam _rType reserve data type
/// @tparam _rSize rererve size
template <typename T, typename _rType, std::int32_t _rSize>
struct PointXD : Point4D<T> {
  _rType reserve[_rSize];
};

template <typename _rType, std::int32_t _rSize>
using Pointxf = PointXD<float, _rType, _rSize>;
template <typename _rType, std::int32_t _rSize>
using Pointxd = PointXD<double, _rType, _rSize>;
template <typename _rType, std::int32_t _rSize>
using Pointxi = PointXD<std::int32_t, _rType, _rSize>;
template <typename _rType, std::int32_t _rSize>
using Pointxii = PointXD<std::int64_t, _rType, _rSize>;

}  // namespace perception
}  // namespace autodrive

#endif